#!/usr/bin/perl
#
# castcopy - get-cast
# Copyright (C) 2007 Nick Bargnesi <nick at den-4.com>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
use strict;
use warnings;
use CastCopy;

my $filename;
my $cfgfile = '/etc/castcopy.cfg';
my $verbose = 0;
set_caller($0);

our $me = $0;
our $filename;
our $localfile;
our $opt_verbose = 0;
our $opt_no_overwr = 0;
our $opt_md5_overwr = 0;
our $opt_iterations = 1;
our $opt_using_lf = 0;
our $old_cksum;
&check_args(@ARGV);
set_verbose($opt_verbose);
init($cfgfile);

my $count = 0;
while ($count < $opt_iterations) {
    if (receive_file($filename, $opt_md5_overwr, $localfile)) {
        exit;
    } else {
        $count++;
    }
}

sub check_args {
    my $arg = shift;
    while ($arg) {
        if ($arg eq "--help" or $arg eq "-H") {
            &usage_options_and_exit;
        } elsif ($arg eq "--md5-overwrite" or $arg eq "-MO" or $arg eq "-mo") {
            $opt_md5_overwr = 1;
        } elsif ($arg eq "--no-overwrite" or $arg eq "-NO" or $arg eq "-no") {
            $opt_no_overwr = 1;
        } elsif ($arg eq "--verbose" or $arg eq "-V" or $arg eq "-v") {
            $opt_verbose = 1;
        } elsif ($arg eq "--iterations" or $arg eq "-I" or $arg eq "-i") {
            $arg = shift;
            $opt_iterations = $arg;
            if ($opt_iterations eq "") {
                &usage_and_exit;
            }
        } elsif ($arg eq "--config" or $arg eq "-C" or $arg eq "-c") {
            $arg = shift;
            $cfgfile = $arg;
            if (! $cfgfile) {
                &usage_and_exit;
            }
        } elsif ($arg eq "--localfile" or $arg eq "-L" or $arg eq "-l") {
            $arg = shift;
            $localfile = $arg;
            if ($localfile eq "") {
                &usage_and_exit;
            }
            $opt_using_lf = 1;
        } else {
            if ($filename) {
                print "$me: file already specified ($filename)\n";
                &usage_and_exit;
            }
            $filename = $arg;
        }
        $arg = shift;
    }

    if (! $filename) {
        &usage_and_exit;
    }

    if ($opt_using_lf) {
        if ( -e $localfile) {
            if ($opt_no_overwr) {
                print "$me: local file exists and --no-overwrite (-NO) requested\n";
                exit;
            }
            if ( ! -w $localfile) {
                print "$me: permission denied (no write access to $localfile?)\n";
                exit;
            }
        }
    } else {
        if ( -e $filename) {
            if ($opt_no_overwr) {
                print "$me: file exists and --no-overwrite (-NO) requested\n";
                exit;
            }
            if ( ! -w $filename) {
                print "$me: permission denied (no write access to $filename?)\n";
                exit;
            }
        }
    }
}

#my $i;
#my $buf;
#my $data;
#my @tokens;
#my $md5;
#my $sock = IO::Socket::Multicast->new(LocalPort=>CONTROL_PORT, ReuseAddr=>1);
#$sock->mcast_add(CONTROL_ADDR) or die "Could not set control group: $!\n";
#while ($i < $opt_iterations) {
#    $sock->recv($data, CONTROL_BUFFER_SIZE) or die "Could not receive signal: $!\n";
#    @tokens = split / /, $data;
#    if ($tokens[0] eq CKSUM) {
#        &verbose(CKSUM . ": $tokens[1]");
#        $cksum = $tokens[1];
#        if ($opt_md5_overwr) {
#            if ($cksum eq $old_cksum) {
#                &verbose("checksums match");
#                $sock->close;
#                exit;
#            }
#        }
#        $sock->recv($data, CONTROL_BUFFER_SIZE) or die "Could not receive signal: $!\n";
#        @tokens = split / /, $data;
#        if ($tokens[0] eq PKTS) {
#            &verbose(PKTS . ": $tokens[1]");
#            $pkts = $tokens[1];
#            $sock->recv($data, CONTROL_BUFFER_SIZE) or die "Could not receive signal: $!\n";
#            @tokens = split / /, $data;
#            if ($tokens[0] eq CTS) {
#                $server_file = $data;
#                $data =~ s/CTS //g;
#                &verbose(CTS . ": $data");
#                if ($data eq $filename) {
#                    $sock->close;
#                    &receive_file;
#                } else {
#                    &verbose("ignoring file");
#                    $i++;
#                }
#            } else {
#                &verbose("received junk: $data");
#            }
#        } elsif ($tokens[0] eq CTS) {
#            &verbose("received extraneous CTS signal");
#        } else {
#            &verbose("received junk: $data");
#            $i++;
#        }
#    } elsif ($tokens[0] eq CTS) {
#        &verbose("received extraneous CTS signal");
#    } else {
#        &verbose("received junk: $data");
#        $i++;
#    }
#}
#&verbose("maximum iterations reached");
#$sock->close;
#
#sub receive_file {
#    my $i = 1;
#    my $data;
#    my $sock = IO::Socket::Multicast->new(LocalPort=>DATA_PORT, ReuseAddr=>1);
#    if ($localfile eq "") {
#        open(FILE, ">$filename") or die "Could not open $filename for writing: $!\n";
#    } else {
#        open(FILE, ">$localfile") or die "Could not open $localfile for writing: $!\n";
#    }
#    binmode(FILE);
#    $sock->mcast_add(DATA_ADDR) or die "Could not set control group: $!\n";
#    while ($i <= $pkts) {
#        $sock->recv($data, DATA_BUFFER_SIZE);
#        syswrite(FILE, $data);
#        $i++;
#    }
#    $sock->close;
#    exit;
#}

sub usage_and_exit {
    print "Usage: $0 [OPTION]... [FILENAME]\n";
    print "Try \'$0 --help\' for more information.\n";
    exit;
}

sub usage_options_and_exit {
    print "Usage: $0 [OPTION]... [FILENAME]\n";
    print "Get FILENAME from the multicast channel.\n";
    print "Example: $0 $ENV{'HOME'}/.bashrc\n";
    print "\n";
    print "Options:\n";
    print "\n";
    print "  --help, -H\t\tDisplays this help.\n";
    print "  --verbose, -V\t\tVerbose mode.\n";
    print "  --config, -C\t\tConfiguration file, defaults to '/etc/castcopy.cfg'.\n";
    print "\n";
    print "  --no-overwrite, -NO\tPrevent overwriting existing files.\n";
    print "  --md5-overwrite, -MO\tOverwrite when MD5 checksums differ.\n";
    print "\n";
    print "  Advanced Options:\n";
    print "\n";
    print "    --localfile (-L) [FILENAME]:\n";
    print "        Override filename in cast with the specified filename.\n";
    print "\n";
    print "    --iteration (-I) [1-n]:\n";
    print "        Defines the number of iterations get-cast will execute\n"
        . "        searching for the specified file before giving up.\n";
    exit;
}

__END__

=head1 NAME

modern - I am a modern module

